package social.server.main;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import social.server.Exceptions.AlreadyApprovedRequestException;
import social.server.Exceptions.AlreadyDoneItemRequestException;
import social.server.Exceptions.AlreadyRequestedDevolutionException;
import social.server.Exceptions.AlreadyReturnedItemException;
import social.server.Exceptions.InexistentFriendShipException;
import social.server.Exceptions.InexistentItemException;
import social.server.Exceptions.InexistentRequestItemException;
import social.server.Exceptions.InvalidAddressException;
import social.server.Exceptions.InvalidDaysException;
import social.server.Exceptions.InvalidIdItemExeption;
import social.server.Exceptions.InvalidLoginException;
import social.server.Exceptions.InvalidNameAtributeException;
import social.server.Exceptions.InvalidRemoveIteminLoan;
import social.server.Exceptions.InvalidRequestIdItemException;
import social.server.Exceptions.LoanedItemException;
import social.server.Exceptions.NoActivitysException;
import social.server.Exceptions.NoIdSessionFoundException;
import social.server.Exceptions.NoPossessionException;
import social.server.Exceptions.OnlyOwnerCanApproveException;
import social.server.Exceptions.OnlyOwnerCanRequestDevolutionException;
import social.server.Exceptions.UserNotFriendException;
import social.server.historicActivity.HistoricActivity;
import social.server.historicActivity.HistoricManager;
import social.server.historicActivity.PublicateRequestActivity;

/**
 * 
 * @author Grupo: Brunna Amorim, Caio Libanio, Diego de Lima, Dimitre Andrew e
 *         Rafael Cavalcante
 * 
 */
public class User {

	private String name, login, idSession;
	private String newAddress;
	private int reputation;
	private Location position;

	private String[] lastVisits = new String[7];

	private LinkedList<RequestItem> inProgessRequests = new LinkedList<RequestItem>();
	private LinkedList<HistoricActivity> userHistoric = new LinkedList<HistoricActivity>();

	private List<String> requestsMessages = new ArrayList<String>();
	private List<String> requestedItemCodes = new ArrayList<String>();
	private List<String> friendList = new ArrayList<String>();
	private List<Item> itemList = new ArrayList<Item>();
	private List<Item> loanItem = new ArrayList<Item>();
	private List<RequestItem> pendingRequestList = new ArrayList<RequestItem>();
	private List<Request> friendshipRequest = new ArrayList<Request>();
	private MessageManager messagesManager = new MessageManager();

	/**
	 * Cria um usuario a partir do login, do nome e do endereco
	 * 
	 * @param login
	 *            Login do usuario
	 * @param name
	 *            nome do usuario
	 * @param address
	 *            endereco do usuario
	 * @throws Exception
	 *             Login, nome ou endereco invalidos
	 */
	public User(String login, String name, String address) throws Exception {
		if (name == null || name.isEmpty()) {
			throw new InvalidNameAtributeException();
		}
		if (checkLogin(login) == false) {
			throw new InvalidLoginException();
		}
		if (address.isEmpty() || address == null) {
			throw new InvalidAddressException();
		}

		this.name = name;
		this.idSession = login;
		this.newAddress = address;
		this.login = login;
		this.reputation = 0;
		this.position = Location.sayLocation(Location.addressURL(address),
				login);
	}

	/**
	 * Muda o id da sessao
	 * 
	 * @param id
	 *            Id
	 */
	public void setIdSession(String id) { // aqui
		idSession = id;
	}

	/**
	 * Retorna o id da sessao
	 * 
	 * @return Id
	 */
	public String getIdSession() { // aqui
		return idSession;
	}

	/**
	 * Retorna a lista de amigos do usuario
	 * 
	 * @return Lista de amigos
	 */
	public List<String> getFriendList() {
		return friendList;
	}

	/**
	 * Retorna a lista de itens do usuario
	 * 
	 * @return Lista de itens
	 */
	public List<Item> getItemList() {
		return itemList;
	}

	public List<Item> getLoanList() {
		return loanItem;
	}

	/**
	 * Retorna a lista de requisicoes
	 * 
	 * @return lista
	 */
	public List<String> getRequestsMessages() {
		return requestsMessages;
	}

	/**
	 * retorna a posicao geografica do usuario
	 * 
	 * @return posicao
	 */
	public Location getPosition() {
		return this.position;
	}

	/**
	 * Metodo responsavel por publicar uma requisicao de Item, ou seja, o
	 * usuario usa este metodo para dizer aos seu amigos que ele precisa de um
	 * item.
	 * 
	 * @param itemName
	 *            Nome do item que ele precisa
	 * @param description
	 *            Descricao do Item que ele precisa
	 * @throws Exception
	 */

	public void publicateRequest(String itemName, String description)
			throws Exception {
		Validator.validateItemName(itemName);
		Validator.validateDescriptionName(description);

		PublicateRequestActivity publication = new PublicateRequestActivity(
				login, itemName, description);
		for (HistoricActivity publicationRequest : userHistoric) {
			if (publicationRequest.equals(publication)) {
				throw new Exception("Excessao!");
			}
		}
		addHistoricActivity(publication);
	}

	/**
	 * Metodo responsavel por repassar uma Publicacao adiante ( repassar uma
	 * publicacao de um amigo meu, para todos os meus amigos ).
	 * 
	 * @param idPublication
	 *            Id da publicacao que deve ser retransmitida ( passada a diante
	 *            ).
	 * @throws Exception
	 */

	public void rePublicateRequest(String idPublication) throws Exception {
		User user = System.getInstance().getUser(idPublication.split("/")[0]);
		for (HistoricActivity publication : user.getUserHistoric()) {
			if (publication instanceof PublicateRequestActivity) {
				if (((PublicateRequestActivity) publication).getPublicationId()
						.equals(idPublication)) {
					addHistoricActivity(publication);
					return;
				}

			}

		}

	}

	/**
	 * Retorna a lista de historico de atividades do usuario
	 * 
	 * @return Lista do historico de atividades
	 * @throws Exception
	 */
	public List<HistoricActivity> relationshipHistoric() throws Exception {
		List<HistoricActivity> relationshipHistoricList = new LinkedList<HistoricActivity>();

		Iterator<HistoricActivity> userIt = getUserHistoric().iterator();
		Iterator<String> friendsIt = getFriendList().iterator();
		Iterator<HistoricActivity> friendHistoricIt;

		while (userIt.hasNext()) {
			relationshipHistoricList.add(userIt.next());
		}

		while (friendsIt.hasNext()) {
			friendHistoricIt = System.getInstance().getUser(friendsIt.next())
					.getUserHistoric().iterator();
			while (friendHistoricIt.hasNext()) {
				relationshipHistoricList.add(friendHistoricIt.next());
			}
		}

		if (relationshipHistoricList.isEmpty()) {
			throw new NoActivitysException();
		}

		relationshipHistoricList = System.getInstance()
				.sortRelationshipHistoricList(
						System.getInstance()
								.cleanRelationshipHistoricListFriendAddition(
										relationshipHistoricList, getName()));

		return System.getInstance().sortRelationshipHistoricList(
				System.getInstance()
						.cleanRelationshipHistoricListPublicationActivity(
								relationshipHistoricList));
	}

	/**
	 * Retorna uma lista correspondete ao historico do usuario.
	 * 
	 * @return Uma lista correspondente ao historico do usuario.
	 * @throws NoActivitysException
	 */
	public List<HistoricActivity> getUserHistoric() throws NoActivitysException {
		if (userHistoric.isEmpty()) {
			throw new NoActivitysException();
		}
		return userHistoric;
	}

	/**
	 * Adiciona uma atividade ao historico do usuario.
	 * 
	 * @param activity
	 *            Atividade a ser adicionada.
	 */
	public void addHistoricActivity(HistoricActivity activity) {
		userHistoric.addFirst(activity);
	}

	/**
	 * Adiciona uma mensagem de requisicao da lista de requisicoes
	 * 
	 * @param string
	 *            mensagem
	 */
	public void addRequestMessages(String string) {
		requestsMessages.add(string);
	}

	/**
	 * Remove uma mensagem de requisicao a lista de requisicoes
	 * 
	 * @param i
	 *            numero que representa a mensagem a ser retirada
	 */
	public void removeRequestMessages(int i) {
		requestsMessages.remove(i);
	}

	/**
	 * retorna o nome do usuario
	 * 
	 * @return nome
	 */
	public String getName() {
		return name;
	}

	/**
	 * Muda o nome do usuario para o passado como parametro
	 * 
	 * @param name
	 *            Nome
	 */
	public void setName(String name) {
		if (!(name.equals(null) || name.isEmpty())) {
			this.name = name;
		}
	}

	/**
	 * Retorna o login do usuario
	 * 
	 * @return Login
	 */
	public String getLogin() {
		return login;
	}

	/**
	 * Retorna a lista de requisicoes de itens pendentes
	 * 
	 * @return Requisicoes pendentes de itens
	 */
	public List<RequestItem> getPendingRequestList() {
		return pendingRequestList;
	}

	/**
	 * Adiciona uma requisicao de item a lista de requisicoes
	 * 
	 * @param request
	 *            Requisicao
	 */
	public void addPenddingRequestList(RequestItem request) {
		pendingRequestList.add(request);
	}

	/**
	 * Remove uma requisicao de item da lista de requisicoes
	 * 
	 * @param i
	 *            inteiro que representa a requisicao de item a ser removida
	 */
	public void removePendingRequestList(int i) {
		pendingRequestList.remove(i);
	}

	/**
	 * Retorna a lista de requisicoes em progresso
	 * 
	 * @return lista
	 */
	public LinkedList<RequestItem> getInProgressRequestList() {
		return inProgessRequests;
	}

	/**
	 * Adiciona uma requisicao a lista de requisicoes em progresso
	 * 
	 * @param request
	 */
	public void addInProgressRequestList(RequestItem request) {
		inProgessRequests.add(request);
	}

	/**
	 * Remove uma requisicao da lista de requisicoes em progresso
	 * 
	 * @param i
	 *            inteiro que representa a requisicao de item a ser removida
	 */
	public void removeInProgressRequestList(int i) {
		inProgessRequests.remove(i);
	}

	/**
	 * Retorna a lista de adicoes de amigos pendentes getPosition
	 * 
	 * @return lista amigos pendentes
	 * @throws Exception
	 *             Sessao invalida
	 */
	public List<Request> getfriendshipRequestList() throws Exception { // aqui
		if (!(this.idSession.equals(idSession)))
			throw new Exception("Sessão inválida");
		return friendshipRequest;
	}

	/**
	 * Adiciona uma requisicao de amizade
	 * 
	 * @param request
	 *            requisicao
	 */
	public void addfriendshipRequest(Request request) {
		friendshipRequest.add(request);
	}

	/**
	 * Remove uma requisicao de amizade da lista requisicoes
	 * 
	 * @param index
	 *            inteiro que representa a requisicao de amizade a ser removida
	 */
	public void removefriendshipRequest(int index) {
		friendshipRequest.remove(index);
	}

	/**
	 * Metodo responsavel por oferecer um Item em resposta a alguma publicacao,
	 * por meio do IdPublication
	 * 
	 * @param idPublication
	 *            Id da publicacao, para o qual esta oferta deve ser enviada
	 * @param idItem
	 *            Id do Item que deve ser oferecido em resposta a uma Publicacao
	 * @throws Exception
	 */

	public void offerItem(String idPublication, String idItem) throws Exception {
		Validator.validateIdPublication(idPublication);
		Validator.validateIdItem(idItem);

		List<HistoricActivity> historicList = this.relationshipHistoric();
		User user = System.getInstance().getUser(idPublication.split("/")[0]);

		if (!this.isFriend(user.getLogin())) {
			throw new UserNotFriendException();
		}

		Item item = this.getItemById(idItem);

		String assunto = "O usuario " + this.name + " ofereceu o item "
				+ item.getName();
		String menssage = "Item oferecido: " + item.getName() + " - "
				+ item.getDescription();

		messagesManager.sendMessage(this.login, user.getLogin(), assunto,
				menssage, "");

	}

	/**
	 * Manda uma requisicao de item ao usuario passado como parametro
	 * 
	 * @param destinationLogin
	 *            Login do destinatario
	 * @param nameOfProduct
	 *            nome do protudo
	 * @param category
	 *            categoria do produto
	 * @param description
	 *            descricao do produto
	 * @param days
	 * @throws Exception
	 */
	public void requestItem(String destinationLogin, String itemId, int days)
			throws Exception {
		if (days <= 0)
			throw new InvalidDaysException();
		int caso1 = 0;
		int caso2 = 0;
		Item item = null;
		if (!(System.getInstance().getUser(login).isFriend(destinationLogin)))
			throw new UserNotFriendException();
		User destinationUser = System.getInstance().getUser(destinationLogin);
		for (RequestItem request : destinationUser.getPendingRequestList()) {
			for (String code : requestedItemCodes) {
				if (request.getRequestId().equals(code)) {
					throw new AlreadyDoneItemRequestException();
				}
			}
		}
		for (Item itemTemp : destinationUser.getItemList()) {
			if (itemTemp.getIdItem().equals(itemId)) {
				item = itemTemp;
				if (item.checkState()) {
					RequestItem requestItem = new RequestItem(this.getLogin(),
							destinationLogin, item.getName(), item.getIdItem(),
							days);
					System.getInstance().getUser(destinationLogin)
							.addPenddingRequestList(requestItem);
					requestedItemCodes.add(requestItem.getRequestId());

					return;
				}
				++caso1;

			}
			++caso2;
		}
		if (caso1 != 0) {
			throw new LoanedItemException();
		} else if (caso2 != 0) {
			throw new NoPossessionException();
		}
	}

	/**
	 * Aprova uma requisicao de emprestimo de item
	 * 
	 * @param idRequest
	 *            Id
	 * @throws Exception
	 */
	public void aproveRequestItem(String idRequest) throws Exception {
		RequestItem requestItem = null;
		boolean notFoundRequest = true;

		for (RequestItem request : this.getInProgressRequestList()) {
			if (request.getRequestId().equals(idRequest))
				throw new AlreadyApprovedRequestException();
		}

		if (idRequest == null || idRequest.isEmpty())
			throw new InvalidRequestIdItemException();

		for (String code : requestedItemCodes) {
			if (code.equals(idRequest))
				throw new OnlyOwnerCanApproveException();
		}

		for (RequestItem request : this.getPendingRequestList()) {
			if (request.getRequestId().equals(idRequest)) {
				notFoundRequest = false;
				requestItem = request;
				requestItem.setinProgressRequestStatus(true);
				this.getInProgressRequestList().addFirst(requestItem);
				this.getPendingRequestList().remove(request);
				break;
			}

		}
		if (notFoundRequest == true)
			throw new InexistentRequestItemException();
		if (requestItem == null)
			throw new InexistentRequestItemException();

		User requestingUser = System.getInstance().getUser(
				requestItem.getRequestingUser());
		requestingUser.getInProgressRequestList().addLast(requestItem);

		for (Item item : itemList) {
			if (item.getIdItem().equals(requestItem.getItemId())) {
				item.changeState();
				requestingUser.addItemInLoan(item);
				HistoricManager.loanOnGoingToHistoric(getLogin(),
						item.getName(),
						System.getInstance().getUser(idRequest.split("/")[1])
								.getName());
			}
		}

		for (int i = 0; i < pendingRequestList.size(); i++) {
			if (pendingRequestList.get(i).equals(requestItem)) {
				pendingRequestList.remove(i);
				return;
			}
		}

	}

	/**
	 * Requisicao de devolucao
	 * 
	 * @param requestId
	 * @throws Exception
	 */
	public void requestDevolution(String requestId) throws Exception {
		boolean foundRequest = false;
		Matcher m = null;
		try {
			Pattern p = Pattern.compile("/");
			m = p.matcher(requestId);
		} catch (Exception e) {
			throw new Exception("Identificador do empréstimo é inválido");
		}

		if (requestId == null)
			throw new Exception("Identificador do empréstimo é inválido");
		if (requestId.isEmpty())
			throw new Exception("Identificador do empréstimo é inválido");

		for (RequestItem req : this.getInProgressRequestList()) {
			if (req.getRequestId().equals(requestId)) {
				foundRequest = true;
			}
		}

		if (!foundRequest && requestId.split("/")[0].equals(login))
			throw new Exception("Empréstimo inexistente"); // Razao semelhante
		if (!m.find())
			throw new Exception("Empréstimo inexistente");
		if (!requestId.split("/")[0].equals(idSession))
			throw new OnlyOwnerCanRequestDevolutionException();

		for (RequestItem request : this.getInProgressRequestList()) {
			if (request.getRequestId().equals(requestId)) {
				if (getItemById(request.getItemId()).checkState()) {
					throw new AlreadyReturnedItemException();
				}

				if (request.getCanceledRequest() == true) {
					throw new AlreadyRequestedDevolutionException();
				}
				if (request.getDeadDate().after(
						System.getInstance().getSystemCalendar().getTime())) {
					request.setCanceledRequest(true);
				}
			}
		}
	}

	/**
	 * confirma o termino do emprestimo
	 * 
	 * @param idRequest
	 *            Id
	 * @throws Exception
	 */
	public void confirmDeliveryItem(String idRequest) throws Exception {

		for (RequestItem request : this.getInProgressRequestList()) {
			if (request.getRequestId().equals(idRequest)) {
				request.setinProgressRequestStatus(false);
				System.getInstance().getUser(request.getRequestingUser())
						.incrementReputation();
			}

		}
	}

	/**
	 * Envia uma requisicao de amizade para o usuario passado como parametro
	 * 
	 * @param destinationLogin
	 *            Login do destinatario
	 * @throws Exception
	 */
	public void requestFriendShip(String destinationLogin) throws Exception { // aqui
		if (System.getInstance().getUser(destinationLogin).getFriendList()
				.contains(this.getLogin()))
			throw new Exception("Os usuários já são amigos");
		for (Request request : System.getInstance().getUser(destinationLogin)
				.getfriendshipRequestList()) {
			if (request.getRequestingUser().equals(this.getLogin()))
				throw new Exception("Requisição já solicitada");
		}
		System.getInstance()
				.getUser(destinationLogin)
				.addfriendshipRequest(
						new Request(this.getLogin(), destinationLogin));

	}

	/**
	 * aprova uma requisico de amizade
	 * 
	 * @param requestedLogin
	 *            Login do usuario que enviou a requisicao
	 * @throws Exception
	 */
	public void aproveFriendRequest(String requestedLogin) throws Exception { // aqui

		int cont = 0;
		if (requestedLogin == null || requestedLogin.equals("")
				|| login.equals(""))
			throw new InvalidLoginException();
		if (friendList.contains(requestedLogin))
			throw new Exception("Os usuários já são amigos");
		System.getInstance().getUser(requestedLogin);

		for (Request request : friendshipRequest) {
			if (request.getRequestingUser().equals(requestedLogin)) {
				++cont;
			}
		}
		if (cont == 0)
			throw new Exception("Requisição de amizade inexistente");
		System.getInstance().getUser(requestedLogin).getFriendList().add(login);
		friendList.add(requestedLogin);
		HistoricManager.friendAdditionToHistoric(getLogin(), System
				.getInstance().getUser(requestedLogin).getName());
		HistoricManager.friendAdditionToHistoric(requestedLogin, getName());

		for (int i = 0; i < friendshipRequest.size(); i++) {
			if (friendshipRequest.get(i).getRequestingUser()
					.equals(requestedLogin)) {
				friendshipRequest.remove(i);
			}
		}
	}

	/**
	 * Verifica se o usuario atual eh amigo do usuario passado como parametro
	 * 
	 * @param login
	 *            Login
	 * @return um boolean
	 * @throws Exception
	 */
	public boolean isFriend(String login) throws Exception {

		if (login == null || login.equals(""))
			throw new InvalidLoginException();
		System.getInstance().getUser(login);
		for (String userLogin : friendList) {
			if (userLogin.equals(login)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Desfaz amizade com o usuario passado como parametro
	 * 
	 * @param loginExFriend
	 * @throws Exception
	 */
	public void undoFriendShip(String loginExFriend) throws Exception {
		User exFriend = System.getInstance().getUser(loginExFriend);
		if (loginExFriend.equals(this.login))
			throw new NoIdSessionFoundException();
		boolean existingFriend = false;

		for (int i = 0; i < friendList.size(); i++) {
			if (friendList.get(i).equals(loginExFriend)) {
				friendList.remove(i);
				existingFriend = true;
			}
		}
		if (!existingFriend)
			throw new InexistentFriendShipException();

		for (int i = 0; i < exFriend.getFriendList().size(); i++) {
			if (exFriend.getFriendList().get(i).equals(idSession)) {
				exFriend.getFriendList().remove(i);
			}
		}
		for (int i = 0; i < this.getPendingRequestList().size(); i++) {
			if (this.getPendingRequestList().get(i).getRequestingUser()
					.equals(loginExFriend)) {
				this.getPendingRequestList().remove(i);
			}
		}

	}

	private boolean checkLogin(String login) { // aqui
		// Pattern padrao = Pattern.compile(".+@.+\\.[a-z]+");
		if (login == null || login.isEmpty()) {
			return false;
		}
		Pattern padrao = Pattern.compile("[a-z]+");
		Matcher pesquisa = padrao.matcher(login);
		if (login.contains(",") || login.contains(";") || login.contains("?")
				|| login.contains("&") || login.contains("!")
				|| login.contains(":") || login.contains("*")
				|| login.contains("#")) {
			return false;
		} else if (pesquisa.matches()) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * Adiciona item na lista de itens
	 * 
	 * @param item
	 * @throws Exception
	 */
	public void addItem(Item item) throws Exception {
		itemList.add(item);

		HistoricManager.registerItemToHistoric(getLogin(), item.getName());
	}

	/**
	 * Adiciona um item a lista de itens emprestados.
	 * 
	 * @param item
	 *            Imte a ser adicionado a lista de itens emperstados.
	 */
	public void addItemInLoan(Item item) {
		loanItem.add(item);
	}

	/**
	 * Retorna a lista de itens por nome
	 * 
	 * @param key
	 *            palavra chave
	 * @return lista
	 */
	public List<Item> getItemByName(String key) {
		List<Item> searchedItem = new ArrayList<Item>();

		java.util.Iterator<Item> it = itemList.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (System.getInstance().compareKeys(key, item.getName())) {
				searchedItem.add(item);
			}
		}
		return searchedItem;
	}

	/**
	 * Retorna a lista de itens por categoria
	 * 
	 * @param key
	 *            palavra chave
	 * @return lista de itens
	 */
	public List<Item> getItemByCategory(String key) {
		key = key.toLowerCase();
		List<Item> searchedItem = new ArrayList<Item>();
		java.util.Iterator<Item> it = itemList.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (item.getCategory().contains(key)) {
				searchedItem.add(item);
			}
		}
		return searchedItem;
	}

	/**
	 * Retorna a lista de itens por descricao
	 * 
	 * @param key
	 *            palavra-chave
	 * @return lista
	 */
	public List<Item> getItemByDescription(String key) {
		List<Item> searchedItem = new ArrayList<Item>();

		java.util.Iterator<Item> it = itemList.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (System.getInstance().compareKeys(key, item.getDescription())) {
				searchedItem.add(item);
			}
		}
		return searchedItem;
	}

	/**
	 * Retorna a lista de itens por Id
	 * 
	 * @param key
	 *            palavra-chave
	 * @return lista
	 * @throws InexistentItemException
	 */
	public Item getItemById(String key) throws InexistentItemException {
		java.util.Iterator<Item> it = itemList.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (item.getIdItem().equals(key)) {
				return item;
			}
		}
		throw new InexistentItemException();
	}

	/**
	 * Faz uma busca por um item emprestado usando o id do item como chave.
	 * 
	 * @param key
	 *            id do item a ser buscado.
	 * @return O item correspondente.
	 * @throws InexistentItemException
	 *             Caso o item nao exista.
	 */
	public Item getLoanedItemById(String key) throws InexistentItemException {
		java.util.Iterator<Item> it = loanItem.iterator();
		while (it.hasNext()) {
			Item item = it.next();
			if (item.getIdItem().equals(key)) {
				return item;
			}
		}
		throw new InexistentItemException();
	}

	/**
	 * Devolve item
	 * 
	 * @param item
	 *            item a ser devolvido
	 * @throws Exception
	 */
	public void returnItem(Item item) throws Exception {
		for (Item c : loanItem) {
			if (c.equals(item)) {
				item.setTrue();
				break;
			}
		}
		loanItem.remove(item);
		HistoricManager.loanEndToHistoric(item.getOwner(), item.getName());
	}

	/**
	 * Adiciona amigo
	 * 
	 * @param login
	 *            Login do amigo a ser adicionado.
	 * @throws Exception
	 *             Lança exception ao chamar outros metodos.
	 */
	public void addFriend(String login) throws Exception {
		friendList.add(login);
	}

	/**
	 * Retorna o endereco do usuario.
	 * 
	 * @return O endereco do usuario.
	 */
	public String getNewAddress() {
		return newAddress;
	}

	/**
	 * Retorna a reputacao do usuario
	 * 
	 * @return reputacao
	 */
	public int getReputation() {
		return reputation;
	}

	/**
	 * incrementa a reputacao do usuario
	 */
	public void incrementReputation() {
		++reputation;
		System.getInstance().increaseUserReputation(this.login);
	}

	/**
	 * Deleta o item passado como parametro
	 * 
	 * @param item
	 * @throws InexistentItemException
	 * @throws InvalidIdItemExeption
	 */
	public void deleteItem(Item item) throws Exception {

		if (verifyInItemList(item) && item.checkState()) {
			itemList.remove(item);
		}

		else if (item.getName().equals("") || item.getName().equals(null)) {
			throw new InvalidIdItemExeption();
		}

		else if (!verifyInItemList(item)) {
			throw new InexistentItemException();
		}

		else if (!item.checkState()) {
			throw new InvalidRemoveIteminLoan();
		}

	}

	/**
	 * verifica se o item está em sua lista
	 * 
	 * @param item
	 * @return boolean
	 */
	public boolean verifyInItemList(Item item) {
		for (Item c : itemList) {
			if (c.equals(item)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Muda a distancia do amigo
	 * 
	 * @param double1
	 */
	public void setDistanceToFriend(Double double1) {
		getPosition().distanceToFriend = double1;
	}

	/**
	 * Retorna uma lista contendo ate os ultimos 7 visitantes ao perfil deste
	 * usuario.
	 * 
	 * @return Lista contendo visitantes.
	 */
	public String[] getLastVisits() {
		return lastVisits;
	}

	/**
	 * Adiciona uma visita recente a lista de visitas do usuario.
	 * @param userName 
	 */
	public void addLastVisit(String userName) {
		if (lastVisits.length == 7) {
			lastVisits[6] = null;
		}
		for (int i = lastVisits.length-1; i >= 0; i--) {
			if(!(lastVisits[i] == null)){
				lastVisits[i+1] = lastVisits[i];
			}

		}
		lastVisits[0] = userName;
	}
}
